package com.liziba.unsafe;

import sun.misc.Unsafe;

/**
 * <p>
 *      內存地址操作示例
 * </p>
 *
 * @Author: Liziba
 * @Date: 2021/5/24 21:32
 */
public class OperateMemoryExample {

    /**
     * 1、public native long allocateMemory(long var1);  分配var1字节大小的内存，返回起始地址偏移量
     * 2、public native long reallocateMemory(long var1, long var3);  重新给var1起始地址的内存分配长度为var3字节的内存，返回新的内存起始地址偏移量
     * 3、public native void freeMemory(long var1); 释放起始地址为var1的地址
     *
     * 分配地址的方法还有重分配，都是分配在堆外内存，返回的是一个long类型的地址偏移量。这个偏移量在Java程序中的每一块内存都是唯一的
     *
     */
    public static void operateMemoryUseUnsafe() {

        Unsafe unsafe = UnsafeFactory.getUnsafe();
        // 申请分配8byte的内存
        long address = unsafe.allocateMemory(1L);
        // 初始化内存填充值
        unsafe.putByte(address, (byte)1);
        // 测试输出
        System.out.println(new StringBuilder().append("address: ").append(address).append(" byte value: ").append(unsafe.getByte(address)));

        // 重新分配一个地址
        long newAddress = unsafe.reallocateMemory(address, 8L);
        unsafe.putLong(newAddress, 8888L);
        System.out.println(new StringBuilder().append("address: ").append(newAddress).append(" long value: ").append(unsafe.getLong(newAddress)));

        // 释放地址，注意地址可能被其他使用
        unsafe.freeMemory(newAddress);
        System.out.println(new StringBuilder().append("address: ").append(newAddress).append(" long value: ").append(unsafe.getLong(newAddress)));

    }


    public static void main(String[] args) {
        OperateMemoryExample.operateMemoryUseUnsafe();
    }

}
